<script type="text/javascript" src="./js/mac/flow/base.min.js"></script>
<script type="text/javascript" src="./js/mac/flow/edit.min.js"></script>
<script type="text/javascript" src="./flow/gen/mac/xml.js"></script>
<!-- <script type="text/javascript" src="./flow/gen/mac/java.js"></script> -->
<script type="text/javascript">
$(function(){
	var pg = App.soagov.flowEdit.ui
		, catalog = App.getHashParam('catalog')
		, id = App.getHashParam('id')
		, code = App.getHashParam('code')
		, leftTabs = pg.children('.tabs')
		, nodePl = pg.children('.nodePl')
		, comGrid = pg.children('.grid')
		, cvsBox = pg.children('.cvsBox')
		, cvsPl = $('#flowCvs')
		, cvsEl = document.getElementById('flowCvs')
		, cvsCtx = cvsEl.getContext('2d')
		, flow = Flow.new1({ id: id }, cvsPl)
		, loading = mac.wait('Loading...')
		, propPl = pg.children('.propPl')
		, _flag, _selected, _pos, _com, faces, byMe, coms = {};
	
	var propPg = App.show({
		ctx: 'soagov',
		action: 'nodeProp',
		params:{
			flowId: code,
			catalog: catalog
		}
	}, function(d){
		comGrid.load();
	}, propPl);
	
	// 载入当前flow所依附的对象（服务）
//	$.get(App.ctx + '/' + type + '/get.do', {
//	$.get(App.ctx + '/flow/get.do', {
//		id: id
	$.get(App.ctx + '/flow/get/' + id, {
	}, function(rs) {
		var ro = mac.eval(rs);
		if (!ro.success) {
			loading.close();
			mac.alert(ro.data, ro.params);
			return;
		}
		
		var fo = ro.data;
		faces = ro.faces;
		byMe = ro.byMe;
		var hm = $('#head>.main');
		hm.seek('name').text(fo.name);
		hm.seek('code').text('（' + fo.code + '）');
		hm.seek('path').text('导出路径：' + fo.path);
		
		//载入当前flow所依赖的组件
		$.post(App.ctx + '/com/list.do', {
			id: id,
			pageNo: 1,
			pageSize: 9999
		}, function(rs) {
			var ro = mac.eval(rs);
			if (!ro.success) {
				loading.close();
				mac.alert(ro.data, ro.params);
				return
			}
			$.each(ro.data.list, function(i, c){
				var a = mac.eval(c.json);
				a.o = c.id;
				coms[c.id] = a;
			});
			
			//载入flow的图表
// 			$.get(App.ctx + '/flow/load.do', {
// 				id: id
			$.get(App.ctx + '/flow/load/' + id, {
			}, function(rs) {
				loading.close();
				var ro = mac.eval(rs);
				if (!ro.success) {
					mac.alert(ro.data, ro.params);
					return
				}
				var rd = ro.data;
				
				if (rd) {
					cvsEl.width = rd.m.w;
					cvsEl.height = rd.m.h;
					$.extend(rd, fo);
					flow = Flow.from(rd, coms, faces);
				}
				flow.o = id;
				propPg.init(flow, faces, cvsEl, cvsCtx);
				refresh();
			});
		});
	});
	
	comGrid.mac('grid', {
		cols : [{
			field: 'type', title : '类型', width: 60,
		}, {
			field: 'code', title : '编号', width: 150,
			render: function(r, tr){
				tr.draggable({
					revert: true,
					helper: 'clone',
					start : function(e) {
						_com = r;
						return true;
					}
				});
				return $('<span title="' + r.code + '">' + r.name + '</span>');
			}
		}],
		loader: {
			url: App.ctx + '/com/list.do' ,
			params: { pageNo: 1, pageSize: 200 },
			autoLoad: true
		}
	});
	
	function onDropNode(e){
		var p = getCvsPos(e);
		nodePl.children('.item').removeClass('selected');
		if (_flag != 'arrow') {
			var n = Flow.Nodes[_flag].new1(p);
			flow.addNode(n);
			refresh();
		}
		_flag = null;
	}
	
	cvsPl.droppable({
		drop: function(e, ui) {
			if (_flag) {
				onDropNode(e);
				return;
			}
			// 前面已限制只有 C.COM C.SVC可以被拖动
			if (!_com) {
				return false;
			}
			var o = _com, t = o.type, p = getCvsPos(e);
			if (t == 'subflow') {
				z = Flow.Nodes['subflow'].new2({
					'o': o.id,
					"t" : "subflow",
					"d" : {
						"code" : o.code,
						'ref' : o.ref || o.code,
						"name" : o.name,
						"faceId" : o.faceId,
						"memo" : o.memo,
						"impl" : o.impl,
						"ver" : o.ver
					},
					"m" : {
						"w" : 180,
						"h" : 40,
						"caption" : ''
					}
				}, p);
			} else {
				var a = mac.eval(o.json);
				a.o = o.id;
				z = Flow.Nodes[t].new2(a, p);
			}
			z.setCaption(o.name, cvsCtx.measureText(o.name).width);
			flow.addNode(z);
			refresh();
		}
	});
	
	function toCvsPos(x, y){
		return {
			x: x - 240 - 12 + cvsBox.scrollLeft(),
			y: y - 60 - 12 + cvsBox.scrollTop()
		}
	}
	function getCvsPos(e){
		return toCvsPos(e.clientX, e.clientY);
	}
	function refresh(){
		flow.draw(cvsCtx);
	}
	
	function pullArrow(n0, p){
		if (!n0.n){
			alert('此节点不能有后继');
			return;
		}
		if (n0.n.id){
			alert('此节点只能有一个后继');
			return;
		}
		var t0 = n0.t;
		if (t0 == 'judge' && n0.count(1) > 1) {
			alert('判定节点只能有两个后继');
			return;
		}
		var aw = Flow.ArrowNode.new1(n0.byAnchor(p), p);
		cvsPl.bind('mousemove', function(e){
			//_a.erase(cvsCtx);
			var p = getCvsPos(e);
			aw.m.x1 = p.x;
			aw.m.y1 = p.y;
			refresh();
			aw.draw(cvsCtx);
			return 0;
		}).one('mouseup', function(e){
			cvsPl.unbind('mousemove');
			var p = getCvsPos(e), ns = flow.nodes;
			for (var i=1; i < ns.length; i++) {
				var n = ns[i];
				if (n && n.id != n0.id && n.onMe && n.onMe(p)) {
					if (!n.p) {
						alert('此节点不能有前驱');
						refresh();
						return 0;
					}
					if (t0 == 'judge') {
						aw.d.tagCode = n0.hasNext('yes')? 'no':'yes';
					} else if (t0 == 'switch') {
// 						while(true) {
							var t = prompt('请输入分支条件的有效值');
// 							if (t) {
								aw.d.tagCode = t;
// 								break;
// 							}
// 						}
					}
					aw.n = n; // 让两个节点建立关系
					aw.p = n0;
					var k = flow.addNode(aw);//先添加才有ID
					if (n.p == -1) {
						n.p = aw;
					} else {
						n.p[k] = aw;
					}
					if (n0.n == -1) {
						n0.n = aw;
					} else {
						n0.n[k] = aw;
					}
					aw.adjust();//变折线
					refresh();
					return 1;
				}
			}
			delete a;
			cvsCtx.clearRect(0, 0, cvsEl.width, cvsEl.height);
			flow.draw(cvsCtx);
			return 0;
		});
	}
	function startDrag(n, p0){
		function mvArrows(a, t, o){
			if (a && a != -1) {
				var z = {};
				if (a.id) {
					z[a.id] = a;
				} else {
					z = a;
				}
				for (var k in z) {
					if (!z[k]) {
						return;
					}
					var m = z[k].m, c = o.getAnchor(m['a' + t]);
					if (c) {
						m['x' + t] = c.x;
						m['y' + t] = c.y;
					}
					z[k].adjust(); //变折线
				}
			}
		}
		_pos = p0;
		cvsPl.bind('mousemove', function(e){
			var p = getCvsPos(e)
				, dx = p.x - _pos.x, dy = p.y - _pos.y;
			_pos = p;
			if (n.t == 'arrow') {
				//TODO 手动调整箭头
			} else {
				//连动与之相连的箭头
				if (_flag == 'move') {
					var ns = flow.nodes;
					for (var i=0; i<ns.length;i++) {
						var a = ns[i];
						if (a && a.s && a.t != 'arrow') {
							a.x += dx;
							a.y += dy;
							mvArrows(a.p, 1, a);
							mvArrows(a.n, 0, a);
						}
					}
				} else {
					n.x = p.x;
					n.y = p.y;
					mvArrows(n.p, 1, n);
					mvArrows(n.n, 0, n);
				}
			}
			refresh();
		}).one('mouseup', function(e){
			cvsPl.unbind('mousemove');
			return 1;
		});
	}
	function unselect1(){
		_selected = null;
		var ns = flow.nodes;
		for (var i=1; i < ns.length; i++) {
			var a = ns[i];
			if (a) {
				a.s = 0;
			}
		}
	}
	
	cvsPl.mousedown(function(e){
		var ns = flow.nodes, p0 = getCvsPos(e);
		if (_flag != 'move') {
			unselect1(flow);
		}
		for (var i=1; i < ns.length; i++) {
			var n = ns[i] || {};
			if (n.onMe && n.onMe(p0)) {
				switch (_flag) {
				case 'arrow':
					pullArrow(n, p0);
					break;
				case 'move':
					startDrag(n, p0);
					break;
				default:
					n.s = 1;
					_selected = n;
					refresh();
					propPg.setProps(n);
					if (n.t != 'arrow') {
						startDrag(n, p0);
					}
				}
				return 1;
			}
		}
		if (!_selected) {
			_selected = flow;
			propPg.setProps(flow);
		}
		if (_flag && _flag != 'move') {
			return;
		}
		_flag = 'select';
		refresh();
		cvsPl.bind('mousemove', function(e){
			refresh();
			var p1 = getCvsPos(e);
			cvsCtx.strokeStyle = '#0000CC';
			cvsCtx.strokeRect(p0.x, p0.y, p1.x - p0.x, p1.y - p0.y);
			return 0;
		}).one('mouseup', function(e){
			cvsPl.unbind('mousemove');
			var p1 = getCvsPos(e), ns = flow.nodes, j = 0;
			for (var i=1; i < ns.length; i++) {
				var n = ns[i];
				if (n && n.t != 'arrow') {
					var m = n.m;
					if (((n.x >= p0.x && n.x <= p1.x) || (n.x <= p0.x && n.x >= p1.x))
						&& ((n.y >= p0.y && n.y <= p1.y) || (n.y <= p0.y && n.y >= p1.y))) {
						n.s = 1;
						j++;
					}
				}
			}
			_flag = (j>1? 'move':null);
			refresh();
			return 1;
		});
		return 1;
	});

	$(window).keypress(function(e){
		var s = _selected;
		if (e.target != document.body) {
			return 0;
		}
		if (e.keyCode == 46 && s) {
			e.stopPropagation();
			flow.delNode(s);
			refresh();
			return 1;
		}
		if (e.ctrlKey && e.which == 97) {
			//e.stopPropagation();
			e.preventDefault();
			_flag = 'move';
			var ns = flow.nodes;
			for (var i=1; i<ns.length; i++) {
				var z = ns[i];
				if (z && z.id && z.t != 'arrow') {
					z.s = 1;
				}
			}
			refresh();
			return 1;
		}
	});

	nodePl.children('.item').click(function(){
		var me = $(this);
		me.siblings().removeClass('selected');
		me.addClass('selected');
		_flag = me.attr('name');
		cvsPl.one('click', function(e){
			onDropNode(e);
		});
		return 0;
	}).draggable({
		revert: true,
		helper: 'clone',
		start : function(e, ui) {
			_flag = $(this).attr('name');
			return true;
		}
	});

	leftTabs.mac('tabs', {
		tabWidth: 80,
		items: [{
			code: 'nodePl',
			title: '节点元素',
			el: nodePl
		},{
			code: 'comGrid',
			title: '组件库',
			el: comGrid
		}]
	}).selectFirst();
	
	function adjust(){
		var h = pg.parent().height();
		pg.height(h);
		leftTabs.height(h - 3);
		leftTabs.adjust();
		comGrid.adjust();
		cvsBox.height(h).width(pg.width() - leftTabs.width()
			- Math.max(286, propPl.width()));
		propPl.height(h);
	}
	$(window).resize(adjust);
	adjust();
	
	$('#menuBtns').append('<button id="menuBtn" class="btn1 hidden">' +
			'</button><button id="saveBtn" class="btn1 hidden"></button>')	
	var mainMenu = $('#mainMenu').mac('menu', {
		children: [{
			title: '导出成图片',
			action : 'expPic',
			icon: 'icon-disk'
		},{
			title : '生成预览',
			icon: 'icon-pencil',
			children: [{
				title : 'XML配置',
				action : 'pvwXml',
				icon: 'icon-pencil',
			}]
		},{
			title : '生成下载',
			icon: 'icon-pencil',
			children: [{
				title : 'XML配置',
				action : 'expXml',
				icon: 'icon-pencil'
			}]
		}]
	}).appendTo($('body'));
	$('#menuBtn').contextMenu({
		menu: mainMenu,
		button: 1,
		anchor: 'el',
		offset: { x: 4, y: 60 }
	}, function(act, el, pos) {
		switch (act) {
		case 'expPic':
			var p = cvsEl.toDataURL("image/png");
//			p = p.replace("image/png", "image/octet-stream");
//			window.location.href = p;
			var w = window.open('about:blank', flow.d.name);
			w.document.write('<img src="' + p +'" alt="' + flow.d.name + '" />');  
			//window.open(p);
			break;
		case 'pvwXml':
			var x = Flow.genXml(flow, faces);
			if (x) {
				App.open({
					closeOnEsc: 1,
					ctx: 'soagov',
					action: 'flowGenPreview',
					params: x
				});
			}
			break;
		case 'expXml':
			var a = $('<a>点击下载</a>').attr({
				download: '1.xml',
				href: 'data:text/xml,' + encodeURI(Flow.genXml(flow, faces))
			});
			$('<div></div>').mac('dialog',{
				title: '文件下载',
				model: true,
				autoOpen: true,
				width: 200,
				height: 80,
				draggable: true,
				el: $('<p style="text-align: center;"></p>').append(a)
			});
			break;
		}
		
		return false;
	}).show();
	
	$('#backBtn').unbind().click(function(){
		App.go('#');
		$('#backBtn').hide();
		$('#menuBtn').hide();
		$('#saveBtn').hide();
	}).show();
	$('#saveBtn').unbind().click(function(){
		var d = flow.d;
		$.post(App.ctx + '/flow/save.do', {
			id: flow.o,
			code: d.code,
			name: d.name,
			faceId: d.faceId,
			impl: d.impl,
			ver: d.ver,
			catalog: d.catalog || catalog,
			type: d.type,
			url: d.url,
			memo: d.memo,
			nexus: flow.getNexus(catalog),//byMe
			faces: flow.getFaces(),
			json: flow.toJson(null, "\t"),
			thumb: cvsEl.toDataURL("image/png")
		}, function(dd){
			var ro = mac.eval(dd);
			if (ro.success) {
				alert('保存成功');
			}else{
				mac.alert(ro.data, ro.params);
			}
		});
	}).show();
});
</script>
<div class="tabs"></div>
<div class="grid" name="comGrid"></div>
<div class="nodePl">
	<div class="item" name="process">
		<div class="nodes process"></div>
		<span>处理节点</span>
	</div>
<!-- 	<div class="item" name="subflow"> -->
<!-- 		<div class="nodes subflow"></div> -->
<!-- 		<span>子流程节点</span> -->
<!-- 	</div> -->
	<div class="item" name="judge">
		<div class="nodes judge"></div>
		<span>判定节点</span>
	</div>
<!-- 	<div class="item" name="input"> -->
<!-- 		<div class="nodes input"></div> -->
<!-- 		<span>输入节点</span> -->
<!-- 	</div> -->
<!-- 	<div class="item" name="output"> -->
<!-- 		<div class="nodes output"></div> -->
<!-- 		<span>输出节点</span> -->
<!-- 	</div> -->
	<div class="item" name="switch">
		<div class="nodes switch"></div>
		<span>多路分支</span>
	</div>
	<div class="item" name="arrow">
		<div class="nodes arrow"></div>
		<span>箭头</span>
	</div>
	<div class="item" name="start">
		<div class="nodes start"></div>
		<span>开始</span>
	</div>
	<div class="item" name="end">
		<div class="nodes end"></div>
		<span>结束</span>
	</div>
	<div class="item" name="try">
		<div class="nodes try"></div>
		<span>try</span>
	</div>
	<div class="item" name="catch">
		<div class="nodes catch"></div>
		<span>catch</span>
	</div>
	<div class="item" name="finally">
		<div class="nodes finally"></div>
		<span>finally</span>
	</div>
	<div class="item" name="yrt">
		<div class="nodes yrt"></div>
		<span>yrt</span>
	</div>
	<div class="item" name="beginTx">
		<div class="nodes beginTx"></div>
		<span>开启事务</span>
	</div>
	<div class="item" name="commitTx">
		<div class="nodes commitTx"></div>
		<span>提交事务</span>
	</div>
	<div class="item" name="fork">
		<div class="nodes fork"></div>
		<span>fork</span>
	</div>
	<div class="item" name="join">
		<div class="nodes join"></div>
		<span>join</span>
	</div>
	<div class="item" name="suspend">
		<div class="nodes suspend"></div>
		<span>suspend</span>
	</div>
	<div class="clear"></div>
</div>
<div class="cvsBox">
	<canvas id="flowCvs" width="800" height="1132"
		style="background-color: #FFFFFF;"></canvas>
</div>
<div class="propPl form"></div>
<div id="mainMenu"></div>